using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace MessageQueues.Abstractions
{
    /// <summary>
    /// 基础抽象的消息队列上下文
    /// </summary>
    public abstract class BasicMqContext : IMqContext
    {
        protected ILogger<BasicMqContext> Logger { get; }

        public BasicMqContext(ILogger<BasicMqContext> logger)
        {
            this.Logger = logger;
        }

        public async Task SubscribeAsync<T>(string name, Action<T> action)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (action == default)
            {
                throw new ArgumentNullException(nameof(action));
            }

            try
            {
                await this.OnSubscribeAsync(name, action);

                this.Logger.LogDebug($"{name} Subscribed");
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex, $"{nameof(Exception)} in {name} Subscribing");
            }
        }

        public async Task PublishAsync<T>(string name, T data)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            try
            {
                await this.OnPublishAsync(name, data);

                this.Logger.LogDebug($"Published on {name}");
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex, $"{nameof(Exception)} in {name} Publishing");
            }
        }

        protected abstract Task OnSubscribeAsync<T>(string name, Action<T> action);

        protected abstract Task OnPublishAsync<T>(string name, T data);
    }
}